
import { _decorator, Component, Node, NodePool, Prefab, instantiate, js, isValid, debug } from 'cc';
import { BaseObject } from './baseObject';
import { poolManager } from './poolManager';
import { poolComponent } from './poolComponent';
import { resourceUtil } from './resourceUtil';
import { Debug } from '../../utils/Debug';
const { ccclass, property } = _decorator;

@ccclass('EntityModule')
export class entityUtil {
    private static _serializeId: number = 0;

    public static getAllEntity(name: any) {
        var allNodes = poolManager.getStack(name);
        if (allNodes == null) return [];
        return allNodes;
    }
    public static showEntity(prefabName: string, parentNode: Node, callback?: (formOwner: Node) => void, bundleKey: string = "", isWorldTransform: boolean = false) {
        this._showEntity(prefabName, parentNode, bundleKey, (entity) => {
            entity.setSiblingIndex(this._serializeId++);
            if (callback) {
                callback(entity);
            }
        }, isWorldTransform);
    }

    public static hideEntity(nodeOwner: Node, isDestroy: boolean = false) {
        this._hideEntity(nodeOwner, isDestroy);
    }
    public static hideAllEntity(name: any, isDestroy: boolean = false) {
        var allNodes = poolManager.getStack(name);
        if (allNodes == null) return;
        for (let i = 0; i < allNodes.length; i++) {
            let item = allNodes[i];
            this.hideEntity(item, isDestroy);
            i--
        }
    }

    private static _showEntity(prefabName: string, parentNode: Node, bundleKey: string, callback?: (formOwner: Node) => void, isWorldTransform: boolean = false) {
        // let self = this as any;
        let names = prefabName.split("/");
        let entityName = names[names.length - 1];
        let p: Prefab = poolManager.getPrefab(entityName);
        if (p == null) {

            if (bundleKey == "") {
                resourceUtil.loadAsset(prefabName, Prefab, (err, res) => {
                    if (err) {
                        Debug.error(err);
                        return;
                    }
                    poolManager.addPrefab(res);
                    this.loadEntityPrefabCompleteCall(prefabName, parentNode, callback, isWorldTransform);
                });
            }
            else {
                resourceUtil.loadBundleRes<Prefab>(bundleKey, prefabName, (err, res) => {
                    if (err) {
                        Debug.error(err);
                        return;
                    }
                    poolManager.addPrefab(res);
                    this.loadEntityPrefabCompleteCall(prefabName, parentNode, callback, isWorldTransform);
                });
            }
            return;
        }
        else {
            this.loadEntityPrefabCompleteCall(prefabName, parentNode, callback, isWorldTransform);
        }

    }

    private static loadEntityPrefabCompleteCall(prefabName: string, parentNode: Node, callback?: (formOwner: Node) => void, isWorldTransform: boolean = false) {
        try {
            let names = prefabName.split("/");
            let entityName = names[names.length - 1];
            let p: Prefab = poolManager.getPrefab(entityName);
            // if (!isValid(parentNode)) {
            //     Debug.log("父节点异常", prefabName);
            //     return;
            // }
            let entity = poolManager.getNode(p, parentNode, isWorldTransform);
            let pc = entity.getComponent(poolComponent) || entity.addComponent(poolComponent);
            pc.tag = entityName;
            entity.active = true;
            if (entity != null && callback) {
                callback(entity);
            }
        }
        catch (e) {
            Debug.warn(e);
            debugger
        }

    }

    private static _hideEntity(entity: Node, data: any, isDestory: boolean = false) {
        if (!entity) return;
        if (isDestory) {
            entity.active = false;
            entity.removeFromParent();
            entity.destroy();
            poolManager.removeStack(entity);
        }
        else {
            entity.active = false;
            // entity.removeFromParent();
            poolManager.putNode(entity);
        }
    }
}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.0/manual/en/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.0/manual/en/scripting/ccclass.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.0/manual/en/scripting/life-cycle-callbacks.html
 */
